<template>
  <div ref="device" class="device-list-container">
    <div ref="table" class="table-container">
      <template v-if="filterDeviceData.length !== 0">
        <section>
          <el-table
            class="el-table"
            :data="showDeviceData"
            :height="ui.height - 60"
            size="mini"
            stripe
            highlight-current-row
            border
            v-loading="isLoading"
            element-loading-text="拼命加载中..."
            @row-click="onTableRowClick"
          >
            <el-table-column type="index" />
            <el-table-column
              v-for="proper in Object.keys(DeviceProperty)"
              :key="proper"
              :prop="proper"
              :label="DeviceProperty[proper]"
              :width="generateColumnHeight(proper)"
            />
            <el-table-column label="操作" fixed="right" width="180">
              <template v-slot:default="scope">
                <i
                  class="el-icon-folder-add"
                  alt="新增"
                  :style="{
                    backgroundColor: 'rgb(100, 180, 255)'
                  }"
                  @click="openPopupShow(scope.row, 'add')"
                />
                <i
                  class="el-icon-edit"
                  alt="编辑"
                  :style="{
                    backgroundColor: 'rgb(90, 255, 150)'
                  }"
                  @click="openPopupShow(scope.row, 'edit')"
                />
                <i
                  class="el-icon-delete"
                  alt="删除"
                  :style="{
                    backgroundColor: 'rgb(255, 110, 80)'
                  }"
                  @click="openPopupShow(scope.row, 'delete')"
                />
              </template>
            </el-table-column>
          </el-table>
        </section>
        <footer>
          <el-pagination
            :current-page="pagination.currentPage"
            :page-sizes="pageSizes"
            :page-size="pagination.pageSize"
            layout="total, sizes, prev, pager, next, jumper"
            :total="totalSize"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
          />
        </footer>
      </template>
      <template v-else>
        <section v-if="!isLoading" class="empty">
          <pcls-empty>当前可展示数据为空</pcls-empty>
        </section>
        <section v-else class="empty">
          <i class="el-icon-loading" />
          正在加载数据...
        </section>
      </template>
    </div>
    <div class="filter-container">
      <el-collapse v-model="activeName" accordion>
        <el-collapse-item title="筛选功能" name="1">
          <template slot="title">
            <i class="header-icon el-icon-set-up" /><span>筛选功能</span>
          </template>
          <section class="row filter">
            <!-- AAY001 设备编号 input -->
            <div class="filter-option">
              <h4>设备编号:</h4>
              <div class="filter">
                <el-input
                  v-model="filter.AAY001[0]"
                  type="text"
                  size="mini"
                  placeholder="请输入内容"
                />
                <span>至</span>
                <el-input
                  v-model="filter.AAY001[1]"
                  type="text"
                  size="mini"
                  placeholder="请输入内容"
                />
              </div>
            </div>
            <!-- AAY010 出厂编号 input -->
            <div class="filter-option">
              <h4>出厂编号:</h4>
              <div class="filter">
                <el-input
                  v-model="filter.AAY010"
                  type="text"
                  size="mini"
                  placeholder="请输入内容"
                />
              </div>
            </div>
            <!-- select -->
            <div v-for="proper in selectProper" :key="proper" class="filter-option">
              <h4>{{ DeviceProperty[proper] }}:</h4>
              <div class="filter">
                <el-select
                  v-model="filter[proper]"
                  filterable
                  multiple
                  collapse-tags
                  size="mini"
                  placeholder="请选择"
                  :popper-append-to-body="true"
                >
                  <el-option
                    v-for="item in filterOptions[proper]"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                  />
                </el-select>
              </div>
            </div>
            <!-- AAY014 检校日期 date -->
            <div class="filter-option">
              <h4>检校日期:</h4>
              <div class="filter">
                <el-date-picker
                  v-model="filter.AAY014"
                  type="datetimerange"
                  size="mini"
                  :picker-options="pickerOptions"
                  range-separator="至"
                  start-placeholder="开始日期"
                  end-placeholder="结束日期"
                  align="right"
                  :default-time="['00:00:00', '23:59:59']"
                />
              </div>
            </div>
            <!-- AAY015 有效期 date -->
            <div class="filter-option">
              <h4>有效期:</h4>
              <div class="filter">
                <el-date-picker
                  v-model="filter.AAY015"
                  type="datetimerange"
                  size="mini"
                  :picker-options="pickerOptions"
                  range-separator="至"
                  start-placeholder="开始日期"
                  end-placeholder="结束日期"
                  align="right"
                  :default-time="['00:00:00', '23:59:59']"
                />
              </div>
            </div>
          </section>
          <section class="filter-button">
            <el-button type="primary" size="mini" @click="clearFilter">清空筛选条件</el-button>
          </section>
        </el-collapse-item>
        <el-collapse-item title="截图功能" name="2">
          <template slot="title">
            <i class="header-icon el-icon-scissors" /><span>截图功能</span>
          </template>
          <header class="current-record">
            <h4>设备编号【{{ edit_cell.AAY001 ? edit_cell.AAY001 : '未选择' }}】：</h4>
            <el-select v-model="currentfilename" size="mini" placeholder="请选择">
              <el-option
                v-for="item in fileOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
          </header>
          <section ref="image" class="img-container">
            <div v-if="currentfilename.length === 0" class="empty">
              <i class="el-icon-box" />
              <span>请点击左侧表格记录获取文件</span>
            </div>
            <div v-else class="preview-container">
              <img
                v-if="['jpg', 'png', 'jpeg'].includes(currentExtName)"
                ref="screenshot"
                :src="currentImgDataUrl"
              />
              <div v-else-if="currentExtName === 'docx'" ref="preview" class="docx" />
              <canvas v-else ref="preview" class="viewer" />
            </div>
          </section>
          <div class="button-container">
            <el-button
              type="primary"
              size="mini"
              :icon="isGenerateImgData ? 'el-icon-loading' : 'el-icon-picture-outline'"
              @click="startScreenShot('table')"
            >
              截图
            </el-button>
            <el-button type="primary" size="mini" icon="el-icon-view" @click="previewScreenShot">
              预览
            </el-button>
            <el-button
              type="primary"
              size="mini"
              :icon="isUploadFile ? 'el-icon-loading' : 'el-icon-upload2'"
              @click="uploadFileById"
            >
              上传
            </el-button>
            <el-popconfirm
              confirm-button-text="确定"
              cancel-button-text="取消"
              icon="el-icon-info"
              icon-color="red"
              title="确定移除该图片？"
              @confirm="deleteScreenShot"
            >
              <el-button slot="reference" type="primary" size="mini" icon="el-icon-delete">
                移除
              </el-button>
            </el-popconfirm>
            <!-- <el-button type="primary" size="mini" @click="deleteScreenShot">移除</el-button> -->
            <!-- <input type="file" @change="uploadPDF"> -->
            <el-upload
              ref="upload"
              class="upload-demo"
              action=""
              :auto-upload="false"
              :show-file-list="false"
              :on-change="uploadLocalFile"
            >
              <el-button slot="trigger" size="small" type="primary" icon="el-icon-folder-opened">
                本地
              </el-button>
            </el-upload>
          </div>
        </el-collapse-item>
        <el-collapse-item title="上传功能" name="3">
          <template slot="title">
            <i class="header-icon el-icon-upload2" /><span>批量上传</span>
          </template>
          <div class="upload-container">
            <el-upload
              ref="upload"
              class="upload-demo"
              action=""
              accept=".xls, .xlsx"
              :before-upload="beforeUpload"
              drag
              :auto-upload="true"
              :disabled="rolesList['AAY']['AAY_3'] === '0'"
            >
              <i class="el-icon-upload" />
              <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
              <div slot="tip" class="el-upload__tip">
                <i class="el-icon-info" />只能上传以.xlsx为后缀名的文件
              </div>
            </el-upload>
          </div>
          <div class="upload-button-container">
            <el-button
              type="primary"
              size="mini"
              icon="el-icon-download"
              @click="downloadFile"
              :disabled="rolesList['AAY']['AAY_4'] === '0'"
            >
              表格导出
            </el-button>
            <!-- <el-button type="primary" size="mini" @click="uploadFileManual">文件上传</el-button> -->
          </div>
        </el-collapse-item>
      </el-collapse>
    </div>
    <div v-if="isPopupLayerShow" class="popup-layer">
      <div ref="popup" class="popup-content">
        <header>
          {{ popup_type === 'add' ? '新增记录' : popup_type === 'edit' ? '编辑记录' : '删除记录' }}
        </header>
        <section>
          <div v-for="setting in DeviceSettingList" :key="setting.proper" class="filter-option">
            <h4>
              {{ setting.label }}
              <span>{{ setting.need ? '*' : '' }}</span>
            </h4>
            <div class="filter">
              <el-input
                v-if="['input', 'textarea'].includes(setting.type)"
                v-model="edit_cell[setting.proper]"
                :type="setting.type === 'input' ? 'text' : 'textarea'"
                size="mini"
                :autosize="{ minRows: 1, maxRows: 2 }"
                :disabled="generateDisabled() ? true : setting.disabled"
                placeholder="请输入内容"
              />
              <el-select
                v-if="setting.type === 'select'"
                v-model="edit_cell[setting.proper]"
                filterable
                allow-create
                size="mini"
                placeholder="请选择"
                :disabled="generateDisabled() ? true : setting.disabled"
              >
                <el-option
                  v-for="item in filterOptions[setting.proper]"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value"
                />
              </el-select>
              <el-date-picker
                v-if="['date', 'datetime'].includes(setting.type)"
                v-model="edit_cell[setting.proper]"
                :type="setting.type"
                size="mini"
                placeholder="选择日期"
                :disabled="generateDisabled() ? true : setting.disabled"
              />
            </div>
          </div>
        </section>
        <footer>
          <el-popconfirm
            v-if="popup_type === 'edit'"
            confirm-button-text="确定"
            cancel-button-text="取消"
            icon="el-icon-info"
            icon-color="red"
            title="确定修改当前记录？"
            @confirm="operationRecord"
          >
            <el-button
              slot="reference"
              type="primary"
              size="mini"
              :disabled="rolesList['AAY']['AAY_0'] === '0'"
            >
              确认修改
            </el-button>
          </el-popconfirm>
          <el-popconfirm
            v-else-if="popup_type === 'add'"
            confirm-button-text="确定"
            cancel-button-text="取消"
            icon="el-icon-info"
            icon-color="red"
            title="确定添加当前记录？"
            @confirm="operationRecord"
          >
            <el-button
              slot="reference"
              type="primary"
              size="mini"
              :disabled="rolesList['AAY']['AAY_1'] === '0'"
            >
              确认新增
            </el-button>
          </el-popconfirm>
          <el-popconfirm
            v-else
            confirm-button-text="确定"
            cancel-button-text="取消"
            icon="el-icon-info"
            icon-color="red"
            title="确定删除当前记录？"
            @confirm="operationRecord"
          >
            <el-button
              slot="reference"
              type="primary"
              size="mini"
              :disabled="rolesList['AAY']['AAY_2'] === '0'"
            >
              确认删除
            </el-button>
          </el-popconfirm>
          <el-button type="primary" size="mini" @click="closePopupLayer">关闭页面</el-button>
          <el-button type="primary" size="mini" @click="startScreenShot('popup')">
            开始截图
          </el-button>
        </footer>
      </div>
    </div>
    <!-- <div v-if="isDeleteLayerShow" class="popup-layer delete">
    <div class="popup-content">
        <header>确定删除id为 {{ edit_cell.id }} 的记录吗？</header>
        <footer>
        <el-button
            type="primary"
            size="mini"
            @click="deleteRow"
        >
            确认删除
        </el-button>
        <el-button type="primary" size="mini" @click="closePopupLayer">放弃删除</el-button>
        </footer>
    </div>
    </div> -->
    <div v-if="isPreviewScreenShot" class="popup-layer preview" @click="closePopupLayer">
      <div
        :class="{
          'popup-content': true,
          'docx-type': ['docx'].includes(currentExtName)
        }"
      >
        <img v-if="['jpg', 'png', 'jpeg'].includes(currentExtName)" :src="currentImgDataUrl" />
        <div v-else-if="currentExtName === 'docx'" ref="viewer" class="docx" />
        <template v-else>
          <canvas ref="viewer" />
          <span>
            第 {{ currentPDFMessage.currentPage }} 页 / 共 {{ currentPDFMessage.pageSize }} 页
          </span>
          <i class="prev el-icon-arrow-left" @click.stop="renderNewPage('prev')" />
          <i class="next el-icon-arrow-right" @click.stop="renderNewPage('next')" />
        </template>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import Vue from 'vue'
import { Component, Watch, Ref } from 'vue-property-decorator'
import {
  GetMeterList,
  AddMeterRecord,
  UpdateMeterRecord,
  DeleteMeterRecord,
  GetFileListById,
  GetFileData,
  UploadFileByID,
  DeleteFileByID
} from '@/api/device'
// 组件
import { Message } from 'element-ui'
import PclsEmpty from '@/components/basic/empty.vue'
// 三方库
import html2canvas from 'html2canvas'
import * as PDFJS from 'pdfjs-dist/legacy/build/pdf'
import { RenderParameters } from 'pdfjs-dist/types/src/display/api'
import { renderAsync } from 'docx-preview'
import XLSX from 'xlsx'
// 功能函数
import { json2xlsx } from '@/utils/file'
import { DeviceProperty, DeviceSettingList } from './settings/deviceListSetting'
import { Device, DeviceProperties } from './settings/deviceListSetting'
import { readBuffer, dataURLtoFile, getExtend } from '@/utils/file'
import { deepClone, formatTime } from '@/utils/specificFunc'
// 类型声明
import { AxiosResponse } from 'axios'
import { ResponseDataType } from '@/interface/Basic'
import { Getter } from 'vuex-class'
type Dictionary<T> = {
  [key: string]: T
}
interface filterOptionsType {
  [key: string]: {
    text: string
    label: string
    value: string
  }[]
}
@Component({
  components: {
    PclsEmpty
  }
})
class deviceList extends Vue {
  // Ref
  @Ref() readonly table!: HTMLElement
  @Ref() readonly popup!: HTMLElement
  @Ref() readonly viewer!: HTMLElement
  @Ref() readonly preview!: HTMLElement | HTMLCanvasElement
  // Getter
  @Getter('name') username!: string
  @Getter('rolesList') rolesList!: Dictionary<Dictionary<string>>
  // data
  ui: {
    height: number
  } = {
    height: 0
  }
  DeviceProperty: typeof DeviceProperty = DeviceProperty
  // DevicePropertyWithoutID: typeof DevicePropertyWithoutID = DevicePropertyWithoutID
  DeviceSettingList: typeof DeviceSettingList = DeviceSettingList
  originDeviceData: Device[] = []
  filterDeviceData: Device[] = []
  showDeviceData: Device[] = []
  // pagination
  pageSizes: number[] = [20, 30, 50]
  // select type
  selectProper: DeviceProperties[] = [
    'AAY002',
    'AAY003',
    'AAY005',
    'AAY007',
    'AAY011',
    'AAY012',
    'AAY017',
    'AAY024'
  ]
  currentSelectProper: DeviceProperties = 'AAY002'
  filterOptions: filterOptionsType = {
    AAY002: [],
    AAY003: [],
    AAY005: [],
    AAY007: [],
    AAY011: [],
    AAY012: [],
    AAY017: [],
    AAY022: [],
    AAY024: []
  }
  // date type
  pickerOptions = {
    shortcuts: [
      {
        text: '最近一周',
        onClick(picker: any) {
          const end = new Date()
          const start = new Date()
          start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
          picker.$emit('pick', [start, end])
        }
      },
      {
        text: '最近一个月',
        onClick(picker: any) {
          const end = new Date()
          const start = new Date()
          start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
          picker.$emit('pick', [start, end])
        }
      },
      {
        text: '最近三个月',
        onClick(picker: any) {
          const end = new Date()
          const start = new Date()
          start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
          picker.$emit('pick', [start, end])
        }
      }
    ]
  }
  pagination: Dictionary<number> = {
    currentPage: 1,
    pageSize: 20
  }
  // filter options
  filter: Dictionary<string[] | string> = {
    AAY001: ['', ''],
    AAY002: [],
    AAY003: [],
    AAY005: [],
    AAY007: [],
    AAY010: '',
    AAY011: [],
    AAY012: [],
    AAY014: [],
    AAY015: [],
    AAY017: [],
    AAY024: []
  }
  // collpase
  activeName = '1'
  // isDeleteLayerShow: false,
  popup_type = ''
  edit_cell: Partial<Device> = {}
  // screenshot
  currentfilename = ''
  // img
  currentImgDataUrl = ''
  // pdf 信息
  currentPDFMessage: Dictionary<number> = {
    currentPage: 1,
    pageSize: 0
  }
  // loading
  isLoading = false
  // popup layer
  isPopupLayerShow = false
  isGenerateImgData = false
  isUploadFile = false
  isPreviewScreenShot = false
  // file upload
  fileList: Dictionary<File> = {}
  // 计算属性
  get totalSize() {
    return this.filterDeviceData.length
  }
  get fileOptions() {
    return Object.keys(this.fileList).map(filename => {
      return { label: filename, value: filename }
    })
  }
  get currentExtName() {
    return getExtend(this.currentfilename)
  }
  // 数据监听
  @Watch('filterDeviceData', { deep: true })
  fd_handler() {
    this.onSizeChange()
  }
  @Watch('pagination', { deep: true })
  p_handler() {
    this.onSizeChange()
  }
  @Watch('filter', { deep: true })
  f_handler() {
    this.$set(this.pagination, 'currentPage', 1)
    this.filterData(this.originDeviceData)
  }
  @Watch('currentfilename')
  c_handler(newVal: string) {
    if (newVal === '') return
    this.$nextTick(async () => {
      const ext = getExtend(newVal)
      if (!this.fileList[newVal]) {
        if (!this.edit_cell.id) {
          Message({
            message: 'ID未知，检查是否选中记录'
          })
          return
        }
        const response: AxiosResponse<Blob, any> = await GetFileData({
          id: 'fixedAssets_' + this.edit_cell.id,
          filename: newVal
        })
        const result = response.data
        this.previewFile(
          new File([result], newVal, {
            type: ['jpg'].includes(ext) ? 'image/jpeg' : ext
          }),
          ext,
          'preview'
        )
      } else {
        this.previewFile(this.fileList[newVal], ext, 'preview')
      }
    })
  }
  // 生命周期
  created() {
    this.getMeterList()
  }
  mounted() {
    this.ui = this.table.getBoundingClientRect()
    window.addEventListener('resize', () => {
      this.ui = this.table.getBoundingClientRect()
    })
  }
  destoryed() {
    window.addEventListener('resize', () => {
      return
    })
  }
  // methods
  getMeterList() {
    const params = {
      DBname: '计量器具记录表'
    }
    this.isLoading = true
    GetMeterList(params)
      .then((res: AxiosResponse<Device[]>) => {
        this.dataStandby(res.data)
        this.isLoading = false
      })
      .catch(() => {
        this.isLoading = false
        Message({
          message: '数据获取失败',
          type: 'error'
        })
      })
  }
  dataStandby(data: Device[]) {
    this.originDeviceData = data
    // 归属部门
    const AAY002: string[] = []
    // 设备名称
    const AAY003: string[] = []
    // 型号
    const AAY005: string[] = []
    // 单位
    const AAY007: string[] = []
    // 存放地点
    const AAY011: string[] = []
    // 责任人
    const AAY012: string[] = []
    // 类别
    const AAY017: string[] = []
    // 其他信息1
    let AAY022: string[] = []
    // 操作员
    const AAY024: string[] = []
    // dataStandby
    data.forEach(device => {
      // AAY002
      if (!AAY002.includes(device.AAY002)) AAY002.push(device.AAY002)
      // AAY003
      if (!AAY003.includes(device.AAY003)) AAY003.push(device.AAY003)
      // AAY005
      if (!AAY005.includes(device.AAY005)) AAY005.push(device.AAY005)
      // AAY007
      if (!AAY007.includes(device.AAY007)) AAY007.push(device.AAY007)
      // AAY011
      if (!AAY011.includes(device.AAY011)) AAY011.push(device.AAY011)
      // AAY012
      if (!AAY012.includes(device.AAY012)) AAY012.push(device.AAY012)
      // AAY017
      if (!AAY017.includes(device.AAY017)) AAY017.push(device.AAY017)
      // AAY024
      if (!AAY024.includes(device.AAY024)) AAY024.push(device.AAY024)
    })
    const result = localStorage.getItem('pcls_device_AAY022')
    if (!result) {
      AAY022 = []
      localStorage.setItem('pcls_device_AAY022', JSON.stringify(AAY022))
    } else {
      AAY022 = JSON.parse(result) as string[]
    }
    // 数据格式化
    const _this = this
    function mapList(listName: string, list: string[]) {
      _this.filterOptions[listName] = list.map(li => {
        return {
          text: li,
          label: li,
          value: li
        }
      })
    }
    mapList('AAY002', AAY002)
    mapList('AAY003', AAY003)
    mapList('AAY005', AAY005)
    mapList('AAY007', AAY007)
    mapList('AAY011', AAY011)
    mapList('AAY012', AAY012)
    mapList('AAY017', AAY017)
    mapList('AAY022', AAY022)
    mapList('AAY024', AAY024)
    this.filterData(data)
  }
  // filter relative
  filterData(data: Device[]) {
    // const { meterNo, toolType, department } = this.filter
    const filterKeys = Object.keys(this.filter).filter(proper => {
      if (Array.isArray(this.filter[proper]) && this.filter[proper].length !== 0) {
        return true
      }
      if (typeof this.filter[proper] === 'string' && this.filter[proper].length !== 0) {
        return true
      }
      return false
    })
    const _AAY001 = this.filter.AAY001
    const minNo =
      !filterKeys.includes('AAY001') || _AAY001[0].match(/\d+/) === null
        ? -Infinity
        : Number(_AAY001[0].match(/\d+/)![0])
    const maxNo =
      !filterKeys.includes('AAY001') || _AAY001[1].match(/\d+/) === null
        ? Infinity
        : Number(_AAY001[1].match(/\d+/)![0])
    const prefix1 =
      !filterKeys.includes('AAY001') || _AAY001[0].match(/[A-z]{1,}/) === null
        ? ''
        : _AAY001[0].match(/[A-z]{1,}/)![0]
    const prefix2 =
      !filterKeys.includes('AAY001') || _AAY001[1].match(/[A-z]{1,}/) === null
        ? ''
        : _AAY001[1].match(/[A-z]{1,}/)![0]
    let beforeData = data
    for (const proper of filterKeys) {
      beforeData = beforeData.filter(device => {
        if (proper === 'AAY001') {
          // AAY001 设备编号
          if (device.AAY001 === '') return true
          if (_AAY001[0] === '' && _AAY001[1] === '') return true
          const match_no = device.AAY001.match(/\d+/)
          const match_code = device.AAY001.match(/[A-z]{1,}/)
          const no = match_no ? Number(match_no[0]) : 0
          const code = match_code ? match_code[0] : ''
          if (
            no >= minNo &&
            no <= maxNo &&
            ((prefix1 === '' && prefix2 === '') ||
              prefix1.indexOf(code) !== -1 ||
              prefix2.indexOf(code) !== -1)
          ) {
            return true
          } else return false
        } else if (this.selectProper.includes(proper as DeviceProperties)) {
          // 所有 select 类型
          if (this.filter[proper].includes(device[proper as DeviceProperties])) {
            return true
          } else return false
        } else if (proper === 'AAY010') {
          // 出厂编号
          if (device.AAY010.indexOf(this.filter.AAY010 as string) !== -1) {
            return true
          }
          return false
        } else if (['AAY014', 'AAY015'].includes(proper)) {
          const start_time = new Date(this.filter[proper][0]).getTime()
          const end_time = new Date(this.filter[proper][1]).getTime()
          const device_time = new Date(device[proper as DeviceProperties]).getTime()
          if (device_time >= start_time && device_time <= end_time) return true
          return false
        }
      })
    }
    this.filterDeviceData = beforeData
  }
  clearFilter() {
    this.filter = {
      AAY001: ['', ''],
      AAY002: [],
      AAY003: [],
      AAY005: [],
      AAY007: [],
      AAY010: '',
      AAY011: [],
      AAY012: [],
      AAY014: [],
      AAY015: [],
      AAY017: [],
      AAY024: []
    }
  }
  onSizeChange() {
    const { currentPage, pageSize } = this.pagination
    this.showDeviceData = this.filterDeviceData.slice(
      (currentPage - 1) * pageSize,
      currentPage * pageSize
    )
  }
  generateColumnHeight(proper: string) {
    if (['AAY005'].includes(proper)) return 180
    if (['AAY016', 'AAY021', 'AAY023'].includes(proper)) return 150
    if (['AAY006', 'AAY007', 'AAY008', 'AAY009', 'AAY022', 'AAY018'].includes(proper)) {
      return 80
    }
    return 120
  }
  generateFilterList(proper: DeviceProperties) {
    if (this.selectProper.includes(proper)) {
      return this.filterOptions[proper]
    } else {
      return null
    }
  }
  // normal
  isCurrentImageType() {
    return ['jpg', 'png', 'jpeg'].includes(getExtend(this.currentfilename))
  }
  // table operation
  onTableRowClick(row: Device) {
    // if (this.activeName !== '2') return
    this.edit_cell = deepClone(row)
    this.fileList = {}
    // 请求文件类型
    GetFileListById({ id: 'fixedAssets_' + row.id }).then(
      (response: AxiosResponse<ResponseDataType<Dictionary<string>[]>, any>) => {
        const res = response.data
        res.ReturnData.forEach(item => {
          this.$set(this.fileList, item.Name, null)
        })
        this.currentfilename = res.ReturnData[0] ? res.ReturnData[0].Name : ''
      }
    )
  }
  openPopupShow(row: Device, type: string) {
    // 权限校验
    this.isPopupLayerShow = true
    this.popup_type = type
    this.edit_cell = deepClone(row) as Device
  }
  closePopupLayer() {
    this.isPopupLayerShow = false
    // this.isDeleteLayerShow = false
    this.isPreviewScreenShot = false
    // this.edit_cell = {}
  }
  validateRecode(edit_cell: Partial<Device>) {
    if (Object.keys(edit_cell).length === 0) return false
    if (this.popup_type === 'delete') return true
    if (
      (edit_cell as Device).AAY003.trim().length === 0 ||
      (edit_cell as Device).AAY017.trim().length === 0
    ) {
      Message({
        message: '设备名称或类别为空',
        type: 'warning'
      })
      return false
    }
    return true
  }
  operationRecord() {
    // 权限校验
    if (!this.validateRecode(this.edit_cell)) return
    const copiedCell = deepClone(this.edit_cell)
    copiedCell['AAY014'] = copiedCell['AAY014']
      ? formatTime(new Date(copiedCell['AAY014']).getTime(), 'YYYY-MM-DD')
      : ''
    copiedCell['AAY015'] = copiedCell['AAY015']
      ? formatTime(new Date(copiedCell['AAY015']).getTime(), 'YYYY-MM-DD')
      : ''
    copiedCell['AAY023'] = formatTime(new Date().getTime(), 'YYYY-MM-DD-hh-mm-ss')
    copiedCell['AAY024'] = this.username
    if (this.popup_type === 'add') {
      copiedCell['AAY001'] = ''
      AddMeterRecord([copiedCell]).then(() => {
        Message({
          message: '数据添加成功',
          type: 'success'
        })
        this.getMeterList()
      })
    } else if (this.popup_type === 'edit') {
      UpdateMeterRecord(copiedCell).then(() => {
        Message({
          message: '数据修改成功',
          type: 'success'
        })
        this.getMeterList()
      })
    } else {
      this.deleteRow()
    }
    this.closePopupLayer()
  }
  beforeDeleteRow(row: Device) {
    this.edit_cell = deepClone(row)
    // this.isDeleteLayerShow = true
  }
  deleteRow() {
    // 权限校验
    if (!this.edit_cell.id) {
      Message({
        message: 'ID未知，请检查是否选中记录',
        type: 'warning'
      })
      return
    }
    DeleteMeterRecord({ id: this.edit_cell.id })
      .then(() => {
        if (this.showDeviceData.length === 1) {
          this.pagination.currentPage -= 1
        }
        this.getMeterList()
        this.closePopupLayer()
        this.edit_cell = {}
      })
      .catch(() => {
        Message({
          message: '删除失败，请重试',
          type: 'error'
        })
        this.closePopupLayer()
      })
  }
  generateDisabled() {
    const roles = this.rolesList['AAY']
    const popup = this.popup_type
    if (popup === 'add' && roles['AAY_1'] === '0') {
      return true
    } else if (popup === 'edit' && roles['AAY_0'] === '0') {
      return true
    } else if (popup === 'delete') {
      return true
    } else {
      return false
    }
  }
  // pagination relative
  handleSizeChange(e: number) {
    this.pagination.pageSize = e
  }
  handleCurrentChange(e: number) {
    this.pagination.currentPage = e
  }
  // screenshot
  beforeOperation() {
    if (Object.keys(this.edit_cell).length === 0 || !this.edit_cell.id) {
      Message({
        message: '请先选择记录',
        type: 'warning'
      })
      return false
    }
    if (this.currentfilename.length === 0) {
      Message({
        message: '请先选择文件',
        type: 'warning'
      })
      return false
    }
    return true
  }
  startScreenShot(domname: 'table' | 'popup') {
    if (this.isGenerateImgData) return
    if (Object.keys(this.edit_cell).length === 0) {
      Message({
        message: '请先选择记录',
        type: 'warning'
      })
      return false
    }
    this.isGenerateImgData = true
    const dom = this[domname]
    html2canvas(dom, {
      useCORS: true,
      allowTaint: true
    }).then(canvas => {
      const imgData = canvas.toDataURL('image/jpeg', 1.0)
      // this.$refs.screenshot.src = imgData
      const filename = this.generateScreenShotName()
      // this.fileList[filename] = imgData
      this.$set(this.fileList, filename, dataURLtoFile(imgData, filename))
      this.currentImgDataUrl = imgData
      this.currentfilename = filename
      this.isGenerateImgData = false
      Message({
        message: '截图成功',
        type: 'success'
      })
    })
  }
  generateScreenShotName() {
    return '截图-' + new Date().toLocaleString().replaceAll(/(\/)|(:)/g, '-') + '.jpg'
  }
  previewScreenShot() {
    if (!this.beforeOperation()) return
    this.isPreviewScreenShot = true
    this.$nextTick(() => {
      const ext = getExtend(this.currentfilename)
      this.previewFile(this.fileList[this.currentfilename], ext, 'viewer')
    })
  }
  // async uploadPDF(e) {
  //   const file = e.target.files[0]
  //   const name = file.name
  //   const arrayBuffer = await readBuffer(file)
  //   this.$set(this.fileList, name, arrayBuffer)
  //   this.currentfilename = name
  //   // this.previewPdf(arrayBuffer, 'preview')
  // }
  async uploadLocalFile(file: any) {
    const { name, raw } = file
    // const arrayBuffer = await readBuffer(raw)
    this.$set(this.fileList, name, raw)
    this.currentfilename = name
  }
  async renderNewPage(status: 'prev' | 'next') {
    const { currentPage, pageSize } = this.currentPDFMessage
    if (status === 'prev' && currentPage > 1) {
      this.currentPDFMessage.currentPage -= 1
    }
    if (status === 'next' && currentPage < pageSize) {
      this.currentPDFMessage.currentPage += 1
    }
    const buffer = await readBuffer(this.fileList[this.currentfilename])
    this.previewPdf(buffer as ArrayBuffer, 'viewer')
  }
  // 预览文件
  async previewFile(file: File, ext: string, canvasName: 'viewer' | 'preview') {
    if (!this.beforeOperation()) return
    this.$set(this.fileList, file.name, file)
    if (['jpg', 'png'].includes(ext)) {
      this.previewJPG(file)
    } else if (ext === 'pdf') {
      const buffer = await readBuffer(file)
      this.previewPdf(buffer as ArrayBuffer, canvasName)
    } else if (ext === 'docx') {
      const buffer = await readBuffer(file)
      this.previewDocx(buffer as ArrayBuffer, canvasName)
    }
  }
  async previewJPG(buffer: File) {
    // if (this.fileList[buffer.name] !== null) return
    const fr = new FileReader()
    fr.readAsDataURL(buffer)
    fr.onload = e => {
      const result = e.target?.result
      if (!result || result === undefined) return
      this.currentImgDataUrl = result.toString()
    }
  }
  previewPdf(buffer: ArrayBuffer, canvasName: 'viewer' | 'preview') {
    PDFJS.GlobalWorkerOptions.workerSrc = require('pdfjs-dist/legacy/build/pdf.worker.entry.js')
    PDFJS.getDocument(buffer).promise.then(pdfDoc => {
      this.currentPDFMessage.pageSize = pdfDoc.numPages
      const { currentPage } = this.currentPDFMessage
      pdfDoc.getPage(currentPage).then(page => {
        const canvas = this[canvasName] as HTMLCanvasElement
        const ctx: any = canvas.getContext('2d')
        const dpr = window.devicePixelRatio || 1
        const bsr =
          ctx.webkitBackingStorePixelRatio ||
          ctx.mozBackingStorePixelRatio ||
          ctx.msBackingStorePixelRatio ||
          ctx.oBackingStorePixelRatio ||
          ctx.backingStorePixelRatio ||
          1
        const ratio = dpr / bsr
        const viewport = page.getViewport({ scale: 1 })
        canvas.width = viewport.width * ratio
        canvas.height = viewport.height * ratio
        canvas.style.width = viewport.width + 'px'
        canvas.style.height = viewport.height + 'px'
        ctx.setTransform(ratio, 0, 0, ratio, 0, 0)
        if (!ctx) return
        const renderContext: RenderParameters = {
          canvasContext: ctx,
          viewport: viewport
        }
        // 数据渲染到canvas画布上
        page.render(renderContext)
      })
    })
  }
  previewDocx(buffer: ArrayBuffer, canvasName: 'viewer' | 'preview') {
    renderAsync(buffer, this[canvasName], undefined, {
      breakPages: true,
      ignoreLastRenderedPageBreak: true
    })
  }
  deleteScreenShot() {
    if (!this.beforeOperation()) return
    // if (!this.edit_cell.id) return
    DeleteFileByID({
      id: 'fixedAssets_' + this.edit_cell.id,
      fileName: this.currentfilename
    })
      .then(() => {
        Message({
          message: '文件删除成功',
          type: 'success'
        })
        this.$delete(this.fileList, this.currentfilename)
        this.currentfilename =
          Object.keys(this.fileList).length === 0 ? '' : Object.keys(this.fileList)[0]
      })
      .catch(() => {
        Message({
          message: '文件删除失败',
          type: 'error'
        })
      })
  }
  uploadFileById() {
    if (!this.beforeOperation()) return
    const { id } = this.edit_cell
    if (!id) {
      Message({
        message: 'ID未知，请确认是否选择记录',
        type: 'warning'
      })
      return
    }
    let file = this.fileList[this.currentfilename]
    if (file instanceof File) {
      // 文件是 file 类型
    } else {
      file = dataURLtoFile(file, this.currentfilename)
    }
    const fd = new FormData()
    fd.append('id', 'fixedAssets_' + id)
    fd.append('file', this.currentfilename)
    fd.append('file', file)
    UploadFileByID(fd).then(() => {
      Message({
        message: '文件上传成功',
        type: 'warning'
      })
    })
  }
  // .xlsx file upload
  beforeUpload(file: File) {
    if (!/\.(xls|xlsx)$/.test(file.name.toLowerCase())) {
      this.$message({
        message: '上传格式不正确，请上传xls或者xlsx格式',
        type: 'warning'
      })
      return false
    }
    const fileReader = new FileReader()
    fileReader.onload = ev => {
      try {
        const data = ev.target!.result
        const workbook = XLSX.read(data, {
          type: 'binary',
          cellDates: true
        })
        const wsname = workbook.SheetNames[0]
        const date_proper_list = ['AAY014', 'AAY015', 'AAY020']
        const ws: Device[] = XLSX.utils.sheet_to_json(workbook.Sheets[wsname]).map((item: any) => {
          date_proper_list.forEach(li => {
            if (item[li] instanceof Date) {
              const newTime = item[li].getTime() + 24 * 60 * 60 * 1000
              item[li] = new Date(newTime).toLocaleDateString().replaceAll('/', '-')
            }
          })
          item.AAY023 = new Date().toLocaleString().replaceAll('/', '-')
          item.AAY024 = this.username
          Object.keys(item).forEach(key => {
            item[key] = item[key].toString()
          })
          return item as Device
          // const copied_item = item as Device
          // return copied_item
        })
        // this.filterDeviceData.push(...ws)
        AddMeterRecord(ws).then(() => {
          Message({
            message: '数据添加成功',
            type: 'success'
          })
          this.getMeterList()
        })
      } catch (e) {
        return false
      }
    }
    this.isLoading = true
    fileReader.readAsBinaryString(file)
    return false
  }
  downloadFile() {
    if (this.filterDeviceData.length === 0) {
      Message({
        message: '当前可写入文件的数据为空',
        type: 'warning'
      })
    }
    const DeviceProperty = this.DeviceProperty
    const mapDeviceData = this.filterDeviceData.map(device => {
      const newObj: {
        [key: string]: string
      } = {}
      Object.keys(device).forEach(proper => {
        if (proper === 'id') newObj.id = device[proper]
        else {
          newObj[DeviceProperty[proper]] = device[proper as DeviceProperties]
        }
      })
      return newObj
    })
    const filename = '设备列表' + new Date().toLocaleString().replaceAll(/(\/)|(:)/g, '-') + '.xlsx'
    const sheetname = 'sheet1'
    json2xlsx(mapDeviceData, filename, sheetname)
  }
}
export default deviceList
</script>

<style lang="less" scoped>
@import '~@/styles/theme.less';
@import '~@/styles/mixin.less';
@import '~@/styles/variable.less';
.device-list-container {
  box-sizing: border-box;
  padding: 10px 20px;
  height: calc(100vh - 50px);
  display: flex;
  align-items: flex-start;
  justify-content: flex-start;
  #color(background-color, --primary-bg-color);
  .table-container {
    box-sizing: border-box;
    padding: 10px;
    width: 75%;
    height: 100%;
    margin-right: 10px;
    padding-bottom: 5px;
    border-radius: 5px;
    #bg-color(--module-bg-color);
    #shadow-color(0, 0, 4px, 0, --primary-shadow-color);
    overflow: hidden;
    section {
      /deep/.el-table {
        width: 100%;
        #bg-color(--module-bg-color);
        #text-color(--primary-text-color);
        .el-table__cell {
          #text-color(--primary-text-color);
          #bg-color(--module-bg-color);
        }
        .el-table__row--striped {
          .el-table__cell {
            #bg-color(--table-stripe-bg-color);
          }
        }
        .el-table__body-wrapper {
          .el-table__body tr.current-row > td {
            color: #ffffff;
            #bg-color(--primary-blue-color);
            background-color: #659bff;
          }
        }
        .el-table__fixed-right {
          height: 100% !important;
          right: 0 !important;
          #color(background-color, --module-bg-color);
          #shadow-color(-1px, 0, 4px, 0, --primary-shadow-color);
          .el-table__fixed-body-wrapper {
            .el-table__body {
              tr {
                td {
                  .cell {
                    display: flex;
                    align-items: center;
                    justify-content: space-around;
                    i {
                      box-sizing: border-box;
                      padding: 5px 10px;
                      border-radius: 3px;
                      color: #ffffff;
                      cursor: pointer;
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    footer {
      height: 60px;
      display: flex;
      align-items: center;
      justify-content: flex-start;
      /deep/.el-pagination {
        span {
          #color(color, --primary-text-color);
        }
        button {
          #color(color, --primary-text-color);
          #color(background-color, --module-bg-color);
        }
      }
    }
    .empty {
      width: 100%;
      height: 100%;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      #text-color(--primary-text-color);
      i {
        font-size: 24px;
        #text-color(--primary-blue-color);
      }
      /deep/.empty-box {
        span {
          margin-top: 10px;
          font-size: 16px;
          #text-color(--primary-text-color);
        }
        path {
          [data-theme='dark'] & {
            fill: #6d6d6d;
          }
        }
        rect {
          [data-theme='dark'] & {
            fill: #86889a;
          }
        }
        #path-3-2 {
          [data-theme='dark'] & {
            fill: #626370;
          }
        }
        polygon {
          [data-theme='dark'] & {
            fill: #e4e4e4;
          }
        }
      }
    }
  }
  .filter-option {
    width: 100%;
    margin-bottom: 18px;
    display: flex;
    align-items: center;
    justify-content: flex-start;
    h4 {
      margin: 0;
      margin-right: 8px;
      width: 60px;
      white-space: nowrap;
      font-size: 14px;
      font-weight: 400;
      text-align: left;
      color: #555555;
    }
    .filter {
      flex: 1;
      display: flex;
      align-items: center;
      justify-content: space-between;
      span {
        margin: 0 5px;
      }
      .el-select {
        width: 100%;
      }
      .el-date-editor {
        width: 100%;
      }
    }
  }
  .filter-container {
    box-sizing: border-box;
    padding: 10px;
    flex: 1;
    height: 100%;
    min-width: 250px;
    border-radius: 5px;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    align-items: center;
    overflow: auto;
    #bg-color(--module-bg-color);
    #shadow-color(0, 0, 4px, 0, --primary-shadow-color);
    justify-content: flex-start;
    /deep/.el-collapse {
      width: 100%;
      .el-collapse-item {
        .header-icon {
          box-sizing: border-box;
          padding: 5px;
          margin-right: 5px;
          border-radius: 5px;
          font-size: 12px;
          color: #ffffff;
          background-color: rgb(100, 180, 255);
        }
        .el-collapse-item__header,
        .el-collapse-item__content {
          #bg-color(--module-bg-color);
          h4 {
            #text-color(--primary-text-color);
          }
        }
        .el-collapse-item__header {
          span {
            font-size: 14px;
            #text-color(--primary-text-color);
          }
        }
      }
    }
    .row {
      width: 100%;
      overflow: auto;
      .title {
        box-sizing: border-box;
        padding-bottom: 10px;
        margin-bottom: 10px;
        font-size: 16px;
        font-weight: 800;
        color: #808080;
        text-align: left;
        border-bottom: solid 1px #dddddd;
      }
    }
    .filter-button {
      /deep/.el-button {
        width: 100%;
      }
    }
    .current-record {
      margin-bottom: 10px;
      width: 100%;
      display: flex;
      align-items: center;
      justify-content: flex-start;
      h4 {
        margin: 0;
        font-size: 14px;
        font-weight: 400;
        color: #555555;
      }
      .el-select {
        flex: 1;
      }
    }
    .img-container {
      min-height: 150px;
      max-height: 300px;
      margin-bottom: 10px;
      display: flex;
      align-items: flex-start;
      justify-content: flex-start;
      border: solid 1px rgba(0, 0, 0, 0.2);
      transition: all 0.5s ease;
      overflow: auto;
      img {
        width: 100%;
      }
      .empty {
        width: 100%;
        height: 200px;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        font-size: 14px;
        color: #a7a7a7;
        i {
          font-size: 48px;
          color: #c5c5c5;
        }
        span {
          line-height: 28px;
        }
      }
    }
    .button-container {
      width: 100%;
      display: flex;
      flex-wrap: wrap;
      align-items: center;
      justify-content: space-between;
      .el-button {
        margin-bottom: 5px;
        padding: 10px;
        border-radius: 10px;
        font-size: 12px;
      }
      /deep/.upload-demo {
        display: flex;
        align-items: center;
        .el-upload {
          margin-bottom: 0;
        }
      }
    }
    .upload-container {
      /deep/.el-upload {
        width: 100%;
        .el-upload-dragger {
          width: 100%;
        }
      }
      .el-upload__tip {
        margin-bottom: 5px;
      }
    }
    .upload-button-container {
      .el-button {
        width: 100%;
      }
    }
  }
  .popup-layer {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    #color(background-color, --popup-bg-color);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 10;
    .popup-content {
      box-sizing: border-box;
      padding: 10px;
      width: 50%;
      min-height: 30%;
      display: flex;
      flex-direction: column;
      align-items: center;
      border-radius: 10px;
      background-color: #ffffff;
      #color(background-color, --module-bg-color);
      header {
        padding: 10px 0;
        margin-bottom: 10px;
        font-size: 24px;
        font-weight: 800;
        #color(color, --primary-text-color);
      }
      section {
        padding: 0 10px;
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        justify-content: space-between;
        .filter-option {
          width: 30%;
          h4 {
            #color(color, --primary-text-color);
            span {
              color: rgb(255, 38, 0);
            }
          }
        }
      }
      footer {
        width: 40%;
        display: flex;
        justify-content: space-between;
        margin-bottom: 10px;
      }
    }
  }
  .delete {
    .popup-content {
      padding: 15px 30px;
      width: unset;
      min-height: unset;
      header {
        margin-bottom: 0;
        font-size: 16px;
        font-weight: 400;
        color: #808080;
      }
      footer {
        width: 100%;
        display: flex;
        justify-content: space-between;
        padding-top: 10px;
      }
    }
  }
  .preview {
    .popup-content {
      width: unset;
      max-height: 95%;
      padding: 0;
      position: relative;
      transition: all 0.5s ease;
      i {
        position: absolute;
        top: 50%;
        transform: translateY(-50%);
        box-sizing: border-box;
        padding: 15px;
        border-radius: 15px;
        font-size: 16px;
        background-color: #ffffff;
        cursor: pointer;
      }
      span {
        position: absolute;
        left: 50%;
        transform: translateX(-50%);
        bottom: 20px;
        font-size: 14px;
        font-weight: 400;
        color: #808080;
      }
      .prev {
        right: calc(100% + 10px);
      }
      .next {
        left: calc(100% + 10px);
      }
    }
    .docx-type {
      overflow: auto;
    }
    .toolbox {
      i {
        box-sizing: border-box;
        padding: 15px;
        border-radius: 18px;
        font-size: 16px;
        background-color: #ffffff;
        cursor: pointer;
      }
    }
  }
}
.upload-container {
  .upload-demo {
    .el-upload__tip {
      #text-color(--primary-text-color);
    }
  }
}
/deep/.el-button {
  margin-left: 0;
}
/deep/::-webkit-scrollbar {
  width: 5px;
  height: 10px;
}
/deep/::-webkit-scrollbar-thumb {
  visibility: true;
  border-radius: 2px;
  transition: all 0.5s ease;
  #color(background-color, --primary-scroll-color);
}
</style>
